﻿using System;
using System.Reflection;
using metroioc.Container;

namespace MetroIoc
{
    public partial class MetroContainer : IContainer
    {
        readonly LifetimeScope scope = new LifetimeScope();
        
        static readonly string CollectionDefaultKey = Guid.NewGuid().ToString();
        
        public MetroContainer() { }

        internal MetroContainer(MetroContainer parent)
        {
            foreach (var p in parent.scope.Registrations)
            {
                scope.Add(p.Key, p.Value);
            }
        }

        public IConfiguration GetConfiguration()
        {
            return new ContainerConfiguration(this);
        }

        public IContainer CreateChildContainer()
        {
            return this.CreateChild();
        }

        /// <summary>
        /// Create an instance with properties from the container.
        /// Only properties attributed [Inject] will be set.
        /// </summary>
        /// <param name="instance"></param>
        public void BuildUp(object instance)
        {
            var propertyInfoCollection = instance.GetType()
                .GetTypeInfo()
                .DeclaredProperties;

            foreach (var propertyInfo in propertyInfoCollection)
            {
                var info = propertyInfo;
                if (info.GetCustomAttribute<InjectAttribute>() == null) continue;

                object property = null;
                try
                {
                    var fullPropertyName = string.Format("{0}.{1}", instance.GetType().FullName, info.Name);
                    property = Resolve(null, fullPropertyName);
                }
                catch (Exception)
                {
                    property = Resolve(info.PropertyType);
                }
                finally
                {
                    info.SetValue(instance, property, null);
                }
            }
        }
    }
}

